home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / unix / unz50p1.zoo / VMS / vms.c < prev    next >
C/C++ Source or Header  |  1992-07-13  |  25KB  |  1,084 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  * Copyright (C) 1992 Igor Mandrichenko.                                 *
  4.  * Permission is granted to any individual or institution to use, copy,  *
  5.  * or redistribute this software so long as all of the original files    *
  6.  * are included unmodified, that it is not sold for profit, and that     *
  7.  * this copyright notice is retained.                                    *
  8.  *                                                                       *
  9.  *************************************************************************/
  10.  
  11. /*
  12.  *    vms.c  by Igor Mandrichenko
  13.  *    version 1.2-1
  14.  *
  15.  *    This module contains routines to extract VMS file attributes
  16.  *    from extra field and create file with these attributes.  This
  17.  *    source is mainly based on sources of file_io.c from UNZIP 4.1
  18.  *    by Info-ZIP.  [Info-ZIP note:  very little of this code is from
  19.  *    file_io.c; it has virtually been written from the ground up.
  20.  *    Of the few lines which are from the older code, most are mine
  21.  *    (G. Roelofs) and I make no claims upon them.  On the contrary,
  22.  *    my/our thanks to Igor for his contributions!]
  23.  */
  24.  
  25. /*
  26.  *      Revision history:
  27.  *      1.0-1   Mandrichenko    16-feb-1992
  28.  *              Recognize -c option
  29.  *      1.0-2   Mandrichenko    17-feb-1992
  30.  *              Do not use ASYnchroneous mode.
  31.  *      1.0-3   Mandrichenko    2-mar-1992
  32.  *              Make code more standard
  33.  *              Use lrec instead of crec -- unzip4.2p does not provide
  34.  *              crec now.
  35.  *      1.1     Mandrichenko    5-mar-1992
  36.  *              Make use of asynchronous output.
  37.  *              Be ready to extract RMS blocks of invalid size (because diff
  38.  *              VMS version used to compress).
  39.  *      1.1-1   Mandrichenko    11-mar-1992
  40.  *              Use internal file attributes saved in pInfo to decide
  41.  *              if the file is text.  [GRR:  temporarily disabled, since
  42.  *              no way to override and force binary extraction]
  43.  *      1.1-2   Mandrichenko    13-mar-1992
  44.  *              Do not restore owner/protection info if -X not specified.
  45.  *      1.1-3   Mandrichenko    30-may-1992
  46.  *              Set revision date/time to creation date/time if none specified
  47.  *              Take quiet flag into account.
  48.  *      1.1-4   Cave Newt       14-jun-1992
  49.  *              Check zipfile for variable-length format (unzip and zipinfo).
  50.  *    1.2    Mandrichenko    21-jun-1992
  51.  *        Use deflation/inflation for compression of extra blocks
  52.  *        Free all allocated space
  53.  *    1.2-1    Mandrichenko    23-jun-1992
  54.  *        Interactively select an action when file exists
  55.  */
  56.  
  57. #ifdef VMS            /*      VMS only !      */
  58.  
  59. #ifndef SYI$_VERSION
  60. #define SYI$_VERSION 4096    /* VMS 5.4 definition */
  61. #endif
  62.  
  63. #ifndef VAXC
  64.                 /* This definition may be missed */
  65. struct XAB {
  66.     unsigned char xab$b_cod;
  67.     unsigned char xab$b_bln;
  68.     short int xabdef$$_fill_1;
  69.     char *xab$l_nxt;
  70. };
  71.  
  72. #endif
  73.  
  74. #include "unzip.h"
  75. #include <ctype.h>
  76. #include <descrip.h>
  77. #include <syidef.h>
  78.  
  79. #define ERR(s) !((s) & 1)
  80.  
  81. #define BUFS512 8192*2        /* Must be a multiple of 512 */
  82.  
  83. /*
  84. *   Local static storage
  85. */
  86. static struct FAB fileblk;
  87. static struct XABDAT dattim;
  88. static struct XABRDT rdt;
  89. static struct RAB rab;
  90.  
  91. static struct FAB *outfab = 0;
  92. static struct RAB *outrab = 0;
  93. static struct XABFHC *xabfhc = 0;
  94. static struct XABDAT *xabdat = 0;
  95. static struct XABRDT *xabrdt = 0;
  96. static struct XABPRO *xabpro = 0;
  97. static struct XABKEY *xabkey = 0;
  98. static struct XABALL *xaball = 0;
  99. struct XAB *first_xab = 0L, *last_xab = 0L;
  100.  
  101. static char query = 0;
  102. static int text_file = 0;
  103.  
  104. static char locbuf[BUFS512];
  105. static int loccnt = 0;
  106. static char *locptr;
  107.  
  108. static int WriteBuffer();
  109. static int _flush_blocks();
  110. static int _flush_records();
  111. static byte *extract_block();
  112. static void message();
  113. static int get_vms_version();
  114. static void free_up();
  115. static int replace();
  116.  
  117. struct bufdsc
  118. {
  119.     struct bufdsc *next;
  120.     byte *buf;
  121.     int bufcnt;
  122. };
  123.  
  124. static struct bufdsc b1, b2, *curbuf;
  125. static byte buf1[BUFS512], buf2[BUFS512];
  126.  
  127.  
  128. int check_format()        /* return non-0 if format is variable-length */
  129. {
  130.     int rtype;
  131.     struct FAB fab;
  132.  
  133.     fab = cc$rms_fab;
  134.     fab.fab$l_fna = zipfn;
  135.     fab.fab$b_fns = strlen(zipfn);
  136.     sys$open(&fab);
  137.     rtype = fab.fab$b_rfm;
  138.     sys$close(&fab);
  139.  
  140.     if (rtype == FAB$C_VAR || rtype == FAB$C_VFC)
  141.     {
  142.     fprintf(stderr,
  143.         "\n     Error:  zipfile is in variable-length record format.  Please\n\
  144.      run \"bilf l %s\" to convert the zipfile to stream-LF\n\
  145.      record format.  (Bilf.exe, bilf.c and make_bilf.com are included\n\
  146.      in the VMS UnZip source distribution.)\n\n", zipfn);
  147.     return 2;        /* 2:  error in zipfile */
  148.     }
  149.  
  150.     return 0;
  151. }
  152.  
  153.  
  154. #ifndef ZIPINFO
  155.  
  156. int create_output_file()
  157. {                /* return non-0 if sys$create failed */
  158.     int ierr, yr, mo, dy, hh, mm, ss;
  159.     char timbuf[24];        /* length = first entry in "stupid" + 1 */
  160.     int attr_given = 0;        /* =1 if VMS attributes are present in
  161.                 *     extra_field */
  162.  
  163.     rab = cc$rms_rab;        /* fill FAB & RAB with default values */
  164.     fileblk = cc$rms_fab;
  165.  
  166.     text_file =/* pInfo->text || */aflag || cflag;
  167.  
  168.     if (attr_given = find_vms_attrs())
  169.     {
  170.     text_file = 0;
  171.     if (cflag)
  172.     {
  173.         printf("Cannot put VMS file %s to stdout.\n",
  174.            filename);
  175.         free_up();
  176.         return 50;
  177.     }
  178.     }
  179.  
  180.     if (!attr_given)
  181.     {
  182.     outfab = &fileblk;
  183.     outfab->fab$l_xab = 0L;
  184.     if (text_file)
  185.     {
  186.         outfab->fab$b_rfm = FAB$C_VAR;    /* variable length records */
  187.         outfab->fab$b_rat = FAB$M_CR;    /* carriage-return carriage ctrl */
  188.     }
  189.     else
  190.     {
  191.         outfab->fab$b_rfm = FAB$C_STMLF;    /* stream-LF record format */
  192.         outfab->fab$b_rat = FAB$M_CR;    /* carriage-return carriage ctrl */
  193.     }
  194.     }
  195.  
  196.     if (!cflag)
  197.     outfab->fab$l_fna = filename;
  198.     else
  199.     outfab->fab$l_fna = "sys$output:";
  200.  
  201.     outfab->fab$b_fns = strlen(outfab->fab$l_fna);
  202.  
  203.     if ((!attr_given) || xabdat == 0 || xabrdt == 0)    /* Use date/time info
  204.                              *  from zipfile if
  205.                              *  no attributes given
  206.                              */
  207.     {
  208.     static char *month[] =
  209.         {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
  210.          "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
  211.  
  212.     /*  fixed-length string descriptor: */
  213.     struct dsc$descriptor stupid =
  214.         {23, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf};
  215.  
  216.     yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;
  217.     mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
  218.     dy = (lrec.last_mod_file_date & 0x1f);
  219.     hh = (lrec.last_mod_file_time >> 11) & 0x1f;
  220.     mm = (lrec.last_mod_file_time >> 5) & 0x3f;
  221.     ss = (lrec.last_mod_file_time & 0x1f) * 2;
  222.  
  223.     dattim = cc$rms_xabdat;    /* fill XABs with default values */
  224.     rdt = cc$rms_xabrdt;
  225.     sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", dy, month[mo], yr,
  226.         hh, mm, ss);
  227.     sys$bintim(&stupid, &dattim.xab$q_cdt);
  228.     memcpy(&rdt.xab$q_rdt, &dattim.xab$q_cdt, sizeof(rdt.xab$q_rdt));
  229.  
  230.     if ((!attr_given) || xabdat == 0L)
  231.     {
  232.         dattim.xab$l_nxt = outfab->fab$l_xab;
  233.         outfab->fab$l_xab = &dattim;
  234.     }
  235.     }
  236.  
  237.     outfab->fab$w_ifi = 0;    /* Clear IFI. It may be nonzero after ZIP */
  238.  
  239.     ierr = sys$create(outfab);
  240.     if (ierr == RMS$_FEX)
  241.     ierr = replace();
  242.  
  243.     if (ierr == 0)        /* Canceled */
  244.     return free_up(), 1;
  245.  
  246.     if (ERR(ierr))
  247.     {
  248.     char buf[256];
  249.  
  250.     sprintf(buf, "[ Cannot create output file %s ]\n", filename);
  251.     message(buf, ierr);
  252.     message("", outfab->fab$l_stv);
  253.     free_up();
  254.     return (1);
  255.     }
  256.  
  257.     if (!text_file && !cflag)    /* Do not reopen text files and stdout
  258.                 *  Just open them in right mode         */
  259.     {
  260.     /*
  261.     *       Reopen file for Block I/O with no XABs.
  262.     */
  263.     if ((ierr = sys$close(outfab)) != RMS$_NORMAL)
  264.     {
  265. #ifdef DEBUG
  266.         message("[ create_output_file: sys$close failed ]\n", ierr);
  267.         message("", outfab->fab$l_stv);
  268. #endif
  269.         fprintf(stderr, "Can't create output file:  %s\n", filename);
  270.         free_up();
  271.         return (1);
  272.     }
  273.  
  274.  
  275.     outfab->fab$b_fac = FAB$M_BIO | FAB$M_PUT;    /* Get ready for block
  276.                              * output */
  277.     outfab->fab$l_xab = 0L;    /* Unlink all XABs */
  278.  
  279.     if ((ierr = sys$open(outfab)) != RMS$_NORMAL)
  280.     {
  281.         char buf[256];
  282.  
  283.         sprintf(buf, "[ Cannot open output file %s ]\n", filename);
  284.         message(buf, ierr);
  285.